#include "ll_pwm.h"
/************************************************************************************************* 
            Tabel PWM-Pin about stm32f407 pwm channel and pins
┏━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━┓
┃                ┃        Positive output           ┃          negative output          ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━━━━┼━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━┼         ┃
┃   channel      ┃   pin     ┃  pin     ┃   pin     ┃   pin     ┃   pin     ┃   pin     ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM1_CH1     ┃   PA8     |  PE9     |           ┃   PA7     |   PB13    |   PE8     ┃  AF_1   ┃
┃   TIM1_CH2     ┃   PA9     |  PE11    |           ┃   PB0     |   PB14    |   PE10    ┃         ┃
┃   TIM1_CH3     ┃   PA10    |  PE13    |           ┃   PB1     |   PB15    |   PE12    ┃         ┃
┃   TIM1_CH4     ┃   PA11    |  PE14    |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM2_CH2     ┃   PA1     |  PB3     |           ┃           |           |           ┃  AF_1   ┃
┃   TIM2_CH3     ┃   PA2     |  PB10    |           ┃           |           |           ┃         ┃
┃   TIM2_CH4     ┃   PA3     |  PB11    |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM3_CH1     ┃   PA6     |  PB4     |   PC6     ┃           |           |           ┃  AF_2   ┃
┃   TIM3_CH2     ┃   PA7     |  PB5     |   PC7     ┃           |           |           ┃         ┃
┃   TIM3_CH3     ┃   PB0     |  PC8     |           ┃           |           |           ┃         ┃
┃   TIM3_CH4     ┃   PB1     |  PC9     |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM4_CH1     ┃   PB6     |  PD12    |           ┃           |           |           ┃  AF_2   ┃
┃   TIM4_CH2     ┃   PB7     |  PD13    |           ┃           |           |           ┃         ┃
┃   TIM4_CH3     ┃   PB8     |  PD14    |           ┃           |           |           ┃         ┃
┃   TIM4_CH4     ┃   PB9     |  PD15    |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM5_CH1     ┃   PH10    |          |           ┃           |           |           ┃  AF_2   ┃
┃   TIM5_CH2     ┃   PA1     |  PH11    |           ┃           |           |           ┃         ┃
┃   TIM5_CH3     ┃   PA2     |  PH12    |           ┃           |           |           ┃         ┃
┃   TIM5_CH4     ┃   PA3     |  PI0     |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┨━━━━━━━━━┨
┃   TIM8_CH1     ┃   PC6     |  PI5     |           ┃   PA5     |   PA7     |   PH13    ┃  AF_3   ┃
┃   TIM8_CH2     ┃   PC7     |  PI6     |           ┃   PB0     |   PB14    |   PH14    ┃         ┃
┃   TIM8_CH3     ┃   PC8     |  PI7     |           ┃   PB1     |   PB15    |   PH15    ┃         ┃
┃   TIM8_CH4     ┃   PC9     |  PI2     |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM9_CH1     ┃   PA2     |  PE5     |           ┃           |           |           ┃  AF_3   ┃
┃   TIM9_CH2     ┃   PA3     |  PE6     |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM10_CH1    ┃   PB8     |  PF6     |           ┃           |           |           ┃  AF_3   ┃
┃   TIM10_CH2    ┃           |          |           ┃           |           |           ┃         ┃
┃   TIM10_CH3    ┃           |          |           ┃           |           |           ┃         ┃    
┃   TIM10_CH4    ┃           |          |           ┃           |           |           ┃         ┃ 
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨  
┃   TIM11_CH1    ┃   PB9     |  PF7     |           ┃           |           |           ┃  AF_3   ┃         
┃   TIM11_CH2    ┃           |          |           ┃           |           |           ┃         ┃
┃   TIM11_CH3    ┃           |          |           ┃           |           |           ┃         ┃
┃   TIM11_CH4    ┃           |          |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM12_CH1    ┃   PB14    |  PH6     |           ┃           |           |           ┃  AF_9   ┃
┃   TIM12_CH2    ┃   PB15    |  PH9     |           ┃           |           |           ┃         ┃ 
┃   TIM12_CH3    ┃           |          |           ┃           |           |           ┃         ┃
┃   TIM12_CH4    ┃           |          |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM13_CH1    ┃   PA6     |  PF8     |           ┃           |           |           ┃  AF_9   ┃
┃   TIM13_CH2    ┃           |          |           ┃           |           |           ┃         ┃
┃   TIM13_CH3    ┃           |          |           ┃           |           |           ┃         ┃
┃   TIM13_CH4    ┃           |          |           ┃           |           |           ┃         ┃
┠━━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━┨
┃   TIM14_CH1    ┃   PA7     |  PF9     |           ┃           |           |           ┃  AF_9   ┃
┃   TIM14_CH2    ┃           |          |           ┃           |           |           ┃         ┃
┃   TIM14_CH3    ┃           |          |           ┃           |           |           ┃         ┃
┃   TIM14_CH4    ┃           |          |           ┃           |           |           ┃         ┃
┗━━━━━━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━┛
**************************************************************************************************/

/* 在下面的数组中配置pwm使用的引脚id,这里使用了IOTGPIO驱动 */
static uint16_t g_pwmPin[PWM_MAX]={
    PA8, PA9, PA10, PA11,
    PA1, PA2, PA3,
    PA6, PA7, PA0, PB1,
    PB6, PB7, PB8, PB9,
    PH10, PA1, PA2, PA3,
    PC6, PC7, PC8, PC9,
    PA2, PA3,
    PB8,
    PB9,
    PB14, PB15,
    PA6,
    PA7,
};
// pwm对应的定时器
static uint8_t g_pwmTimId[PWM_MAX] = {
    1, 1, 1, 1,
    2, 2, 2,
    3, 3, 3, 3,
    4, 4, 4, 4,
    5, 5, 5, 5,
    8, 8, 8, 8,
    9, 9,
    10, 
    11,
    12,12,
    13,
    14,
};
// pwm对应的通道
static uint8_t g_pwmChId[PWM_MAX]={
    1, 2, 3, 4,
    2, 3, 4,
    1, 2, 3, 4,
    1, 2, 3, 4,
    1, 2, 3, 4,
    1, 2, 3, 4,
    1, 2, 
    1, 
    1, 
    1, 2,
    1, 
    1
};

PWM_Config g_pwmConfig[PWM_MAX];
extern Pin_ST g_pinsGroup[STM32_GPIO_GROUP_MAX*STM32_GPIO_PIN_MAX];

TIM_TypeDef *LL_GET_TIMx(uint8_t id)
{
    switch(id)
    {
        case 1: return TIM1;
        case 2: return TIM2;
        case 3: return TIM3;
        case 4: return TIM4;
        case 5: return TIM5;
        case 6: return TIM6;
        case 7: return TIM6;
        case 8: return TIM8;
        case 9: return TIM9;
        case 10: return TIM10;
        case 11: return TIM11;
        case 12: return TIM12;
        case 13: return TIM13;
        case 14: return TIM14;
    }
}
uint32_t LL_GET_TIM_CHANNEL(uint8_t id)
{
    switch(id)
    {
        case 1: return LL_TIM_CHANNEL_CH1;
        case 2: return LL_TIM_CHANNEL_CH2;
        case 3: return LL_TIM_CHANNEL_CH3;
        case 4: return LL_TIM_CHANNEL_CH4;
    }
}

// 计算定时器参数
// 首先确保占空比精确，数值越大得到的频率越精确
uint8_t CalPwmParam(uint32_t rcc, uint16_t duty, uint32_t freq, uint16_t *pre_div, uint32_t *auto_reload, uint32_t *compare_val)
{
    uint16_t i,j,k;
    for(i=0xffff; i>0; i--){
        // 保证占空比精确
        if(i%duty == 0){
            // 确保自动加载值小于16位满值
            if((i/duty)*100 <= 0xffff){
                // 设置输出比较数值
                *compare_val = i;
                // 设置自动加载数值
                *auto_reload = (i/duty)*100;
                // 设置预分频系数
                *pre_div = rcc/(freq*((i/duty)*100));
                // 保证频率正确
                if(*pre_div * (freq*((i/duty)*100))  == rcc)
				{	printf("cal:%d %d %d\n", *pre_div, *auto_reload, *compare_val);
                    return SUCCESS;
				}
            }
        }
    }
    printf("cal pwm param failed\n");
    return ERROR;
}

// 根据定时器编号，打开对应的时钟
void LL_TIM_EnableClock(TIM_TypeDef *tim)
{
    if(tim==TIM1)       
		LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
    else if(tim==TIM2)  
		LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
    else if(tim==TIM3)  
		LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
    else if(tim==TIM4)  
		LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
    else if(tim==TIM5)  
		LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM5);
    else if(tim==TIM8)  
		LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM8);
    else if(tim==TIM9)  
		LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM9);
    else if(tim==TIM10) 
		LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM10);
    else if(tim==TIM11) 
		LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM11);
    else if(tim==TIM12) 
		LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM12);
    else if(tim==TIM13) 
		LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM13);
    else if(tim==TIM14) 
		LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM14);
}
// 配置GPIO模式
uint8_t LL_PWM_PIN_CONFIG(uint8_t port)
{
    g_pwmConfig[port-1].channel = LL_GET_TIM_CHANNEL(g_pwmChId[port-1]);
    g_pwmConfig[port-1].TIMx = LL_GET_TIMx(g_pwmTimId[port-1]);
    g_pwmConfig[port-1].pin = g_pwmPin[port-1];
    /************************** 设置引脚复用为TIMx模式 ******************/
    if(port-1>=0 && port-1<=6)
        LL_CONFIG_GPIO(g_pwmPin[port-1], LL_GPIO_MODE_ALTERNATE, \
			LL_GPIO_PULL_NO, LL_GPIO_SPEED_FREQ_VERY_HIGH, \
			LL_GPIO_OUTPUT_PUSHPULL, LL_GPIO_AF_1);
    else if(port-1>=7 && port-1<=18)
        LL_CONFIG_GPIO(g_pwmPin[port-1], LL_GPIO_MODE_ALTERNATE, \
			LL_GPIO_PULL_NO, LL_GPIO_SPEED_FREQ_VERY_HIGH, \
			LL_GPIO_OUTPUT_PUSHPULL, LL_GPIO_AF_2);
    else if(port-1>=19 && port-1<=26)
        LL_CONFIG_GPIO(g_pwmPin[port-1], LL_GPIO_MODE_ALTERNATE, \
			LL_GPIO_PULL_NO, LL_GPIO_SPEED_FREQ_VERY_HIGH, \
			LL_GPIO_OUTPUT_PUSHPULL, LL_GPIO_AF_3);
    else if(port-1>=27 && port-1<=30)
        LL_CONFIG_GPIO(g_pwmPin[port-1], LL_GPIO_MODE_ALTERNATE, \
			LL_GPIO_PULL_NO, LL_GPIO_SPEED_FREQ_VERY_HIGH, \
			LL_GPIO_OUTPUT_PUSHPULL, LL_GPIO_AF_9);
    /************************** 初始化引脚端口 ******************/
    STM32_GPIO_GROUP group = g_pwmPin[port-1]/16;
    // 打开时钟
    LL_AHB1_GRP1_EnableClock(LL_GET_GPIO_CLK(group));
    GPIO_TypeDef *GPIOx = LL_GET_GPIOX((group));
    // 初始化引脚
    if(LL_GPIO_Init(GPIOx, &g_pinsGroup[g_pwmPin[port-1]].gpioInitStruct) \
		!= SUCCESS){
        printf("%s line %d error : LL_GPIO_Init PWM pin failed...\n", \
			    __func__, __LINE__);
        return ERROR;
    }
    return SUCCESS;
}